package com.starsea.book.ui.newpage.weidget.banner

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.VelocityTracker
import androidx.core.view.VelocityTrackerCompat
import androidx.core.view.ViewCompat
import androidx.viewpager.widget.ViewPager

/**
 * 描述:继承ViewPager，通过反射方式实现支持低版本上切换动画
 */
class BannerViewPager : ViewPager {
  private var mAllowUserScrollable = true
  private var mAutoPlayDelegate: AutoPlayDelegate? = null

  constructor(context: Context?) : super(context!!)
  constructor(context: Context?, attrs: AttributeSet?) : super(
    context!!, attrs
  )

  /**
   * 设置调用setCurrentItem(int item, boolean smoothScroll)方法时，page切换的时间长度
   *
   * @param duration page切换的时间长度
   */
  fun setPageChangeDuration(duration: Int) {
    try {
      val scrollerField = ViewPager::class.java.getDeclaredField("mScroller")
      scrollerField.isAccessible = true
      scrollerField[this] = BannerScroller(context, duration)
    } catch (e: Exception) {
      e.printStackTrace()
    }
  }

  /**
   * 切换到指定索引的页面，主要用于自动轮播
   *
   * @param position
   */
  fun setBannerCurrentItemInternal(position: Int, smoothScroll: Boolean) {
    val viewpagerClass: Class<*> = ViewPager::class.java
    try {
      val setCurrentItemInternalMethod = viewpagerClass.getDeclaredMethod(
        "setCurrentItemInternal",
        Int::class.javaPrimitiveType,
        Boolean::class.javaPrimitiveType,
        Boolean::class.javaPrimitiveType
      )
      setCurrentItemInternalMethod.isAccessible = true
      setCurrentItemInternalMethod.invoke(this, position, smoothScroll, true)
      ViewCompat.postInvalidateOnAnimation(this)
    } catch (e: Exception) {
      e.printStackTrace()
    }
  }

  /**
   * 设置是否允许用户手指滑动
   *
   * @param allowUserScrollable true表示允许跟随用户触摸滑动，false反之
   */
  fun setAllowUserScrollable(allowUserScrollable: Boolean) {
    mAllowUserScrollable = allowUserScrollable
  }

  override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
    return if (mAllowUserScrollable && adapter != null && adapter!!.count > 0) {
      super.onInterceptTouchEvent(ev)
    } else {
      false
    }
  }

  override fun onTouchEvent(ev: MotionEvent): Boolean {
    return if (mAllowUserScrollable && adapter != null && adapter!!.count > 0) {
      if (mAutoPlayDelegate != null && (ev.action == MotionEvent.ACTION_CANCEL || ev.action == MotionEvent.ACTION_UP)) {
        mAutoPlayDelegate!!.handleAutoPlayActionUpOrCancel(xVelocity)
        false
      } else {
        super.onTouchEvent(ev)
      }
    } else {
      false
    }
  }

  private val xVelocity: Float
    private get() {
      var xVelocity = 0f
      val viewpagerClass: Class<*> = ViewPager::class.java
      try {
        val velocityTrackerField = viewpagerClass.getDeclaredField("mVelocityTracker")
        velocityTrackerField.isAccessible = true
        val velocityTracker = velocityTrackerField[this] as VelocityTracker
        val activePointerIdField = viewpagerClass.getDeclaredField("mActivePointerId")
        activePointerIdField.isAccessible = true
        val maximumVelocityField = viewpagerClass.getDeclaredField("mMaximumVelocity")
        maximumVelocityField.isAccessible = true
        val maximumVelocity = maximumVelocityField.getInt(this)
        velocityTracker.computeCurrentVelocity(1000, maximumVelocity.toFloat())
        xVelocity =
          VelocityTrackerCompat.getXVelocity(velocityTracker, activePointerIdField.getInt(this))
      } catch (e: Exception) {
      }
      return xVelocity
    }

  fun setAutoPlayDelegate(autoPlayDelegate: AutoPlayDelegate?) {
    mAutoPlayDelegate = autoPlayDelegate
  }

  interface AutoPlayDelegate {
    fun handleAutoPlayActionUpOrCancel(xVelocity: Float)
  }
}